package com.yang.my.coon.two;

import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 模拟queue(队列)
 * @Author: Mu_YI
 * @Date: 2019/3/19 23:00
 * @Version 1.0
 */
public class MyQueue {

    private LinkedList<Object> list = new LinkedList<Object>();

    private AtomicInteger atomicInteger = new AtomicInteger(0);

    private final int minSize = 0;
    private final int maxSize;

    public MyQueue(int size) {
        this.maxSize = size;
    }

    private final Object lock = new Object();

    /**
     * 存
     *
     * @param object
     */
    public void push(Object object) {
        try {
            synchronized (lock) {
                while (this.maxSize == atomicInteger.get()) {
                    lock.wait();
                }
                list.add(object);
                atomicInteger.incrementAndGet();
                lock.notify();
                System.out.println("新添加的元素:" + object);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    private Object take() {
        Object res = null;
        synchronized (lock) {
            while (atomicInteger.get() == this.minSize) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            res = list.removeFirst();
            atomicInteger.decrementAndGet();
            // 唤醒宁外一个线程
            lock.notify();
        }
        return res;
    }

    public int getSize() {
        return atomicInteger.get();
    }

    public static void main(String[] args) {

        final MyQueue myQueue = new MyQueue(5);
        myQueue.push("a");
        myQueue.push("b");
        myQueue.push("c");
        myQueue.push("d");
        myQueue.push("e");

        System.out.println("当前容器的长度:" + myQueue.getSize());

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                myQueue.push("f");
                myQueue.push("g");
            }
        }, "t1");

        t1.start();

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                Object o1 = myQueue.take();
                System.out.println("t2线程;移走了:" + o1);
                Object o2 = myQueue.take();
                System.out.println("t2线程:移走了:" + o2);
            }
        }, "t2");

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        t2.start();
    }
}
